package pers.liuchengyin.service.impl;

import com.alibaba.fastjson.JSON;
import org.apache.commons.lang3.StringUtils;
import org.elasticsearch.action.admin.indices.delete.DeleteIndexRequest;
import org.elasticsearch.action.bulk.BulkItemResponse;
import org.elasticsearch.action.bulk.BulkRequest;
import org.elasticsearch.action.bulk.BulkResponse;
import org.elasticsearch.action.delete.DeleteRequest;
import org.elasticsearch.action.delete.DeleteResponse;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.index.IndexResponse;
import org.elasticsearch.action.support.WriteRequest;
import org.elasticsearch.action.update.UpdateRequest;
import org.elasticsearch.action.update.UpdateResponse;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.common.xcontent.XContentType;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
import pers.liuchengyin.config.EsConfig;
import pers.liuchengyin.constants.EsConstants;
import pers.liuchengyin.enums.ErrorCode;
import pers.liuchengyin.pojo.Result;
import pers.liuchengyin.pojo.SkuModel;
import pers.liuchengyin.service.EsSaveService;
import pers.liuchengyin.utils.ResultUtils;

import javax.annotation.Resource;
import java.io.IOException;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @ClassName EsSaveServiceImpl
 * @Description
 * @Author 柳成荫
 * @Date 2022/3/27
 */
@Service
public class EsDocServiceImpl implements EsSaveService {

    @Qualifier("elasticSearchRestClient")
    @Autowired
    private RestHighLevelClient esClient;

    @Override
    public Result<List<String>> saveSku(List<SkuModel> skuModels) {
        BulkRequest bulkRequest = new BulkRequest();
        for (SkuModel skuModel : skuModels) {
            bulkRequest.add(createIndexRequest(EsConstants.SKU_INDEX, JSON.toJSONString(skuModel), skuModel.getSkuId().toString()));
        }
        try {
            BulkResponse bulk = esClient.bulk(bulkRequest, EsConfig.COMMON_OPTIONS);
            if (bulk.hasFailures()) {
                return ResultUtils.failResult(ErrorCode.SYSTEM_ERROR_NET);
            }
            List<String> idList = Arrays.stream(bulk.getItems()).map(BulkItemResponse::getId).collect(Collectors.toList());
            return ResultUtils.successResult(idList);
        } catch (IOException e) {
            e.printStackTrace();
            return ResultUtils.failResult(ErrorCode.SYSTEM_ERROR_NET);
        }
    }

    public Result<String> insert(String indexName, String objJson, String docId) {
        try {
            esClient.index(createIndexRequest(indexName, objJson, docId), EsConfig.COMMON_OPTIONS);
            return ResultUtils.successResult(docId);
        } catch (IOException e) {
            e.printStackTrace();
            return ResultUtils.failResult(ErrorCode.SYSTEM_ERROR_NET);
        }
    }

    public Result<String> update(String indexName, String objJson, String docId) {
        if (StringUtils.isBlank(docId)) {
            return ResultUtils.failResult(ErrorCode.PARAM_ERROR);
        }
        try {
            esClient.update(createUpdateRequest(indexName, objJson, docId), EsConfig.COMMON_OPTIONS);
            return ResultUtils.successResult(docId);
        } catch (IOException e) {
            e.printStackTrace();
            return ResultUtils.failResult(ErrorCode.SYSTEM_ERROR_NET);
        }
    }


    private Result<String> delete(String indexName, String docId){
        if (StringUtils.isBlank(docId)) {
            return ResultUtils.failResult(ErrorCode.PARAM_ERROR);
        }
        try {
            esClient.delete(new DeleteRequest(indexName, docId), EsConfig.COMMON_OPTIONS);
            return ResultUtils.successResult(docId);
        } catch (IOException e) {
            e.printStackTrace();
            return ResultUtils.failResult(ErrorCode.SYSTEM_ERROR_NET);
        }
    }

    private IndexRequest createIndexRequest(String indexName, String objJson, String docId) {
        IndexRequest indexRequest = new IndexRequest(indexName);
        if (StringUtils.isNotBlank(docId)) {
            indexRequest.id(docId);
        }
        indexRequest.source(objJson, XContentType.JSON);
        return indexRequest;
    }

    private UpdateRequest createUpdateRequest(String indexName, String objJson, String docId) {
        UpdateRequest updateRequest = new UpdateRequest(indexName, docId);
        updateRequest.setRefreshPolicy(WriteRequest.RefreshPolicy.IMMEDIATE);
        updateRequest.doc(objJson, XContentType.JSON);
        return updateRequest;
    }
}
